package utils

import (
	"encoding/json"
	"errors"
	"github.com/joho/godotenv"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"
)

type User struct {
	FirstName string    `json:"first_name"`
	LastName  string    `json:"last_name"`
	Birthday  time.Time `json:"birthday"`
}

// Init загружает переменные окружения из файла .env и пользователей из json файла dataFile.
func Init(envFile string, dataFile string) (map[int64]User, int64, error) {
	var users map[int64]User
	var chatID int64
	if err := godotenv.Load(envFile); err != nil {
		return users, chatID, errors.New("не удалось загрузить .env файл")
	}
	users, err := LoadUsers(dataFile)
	if err != nil {
		return users, chatID, errors.New("не удалось загрузить пользователей из файла")
	}
	chatIdText := os.Getenv("CHAT_ID")
	if chatIdText == "" {
		return users, chatID, nil
	}
	chatID, err = strconv.ParseInt(chatIdText, 10, 64)
	if err != nil {
		return users, chatID, errors.New("не удалось преобразовать chat_id из .env в число")
	}
	return users, chatID, nil
}

// SaveUsers сохраняет пользователей в json файл dataFile.
func SaveUsers(users map[int64]User, dataFile string) error {
	data, err := json.Marshal(users)
	if err != nil {
		return err
	}

	err = os.WriteFile(dataFile, data, 0644)
	if err != nil {
		return err
	}

	return nil
}

// LoadUsers загружает пользователей из json файла dataFile.
func LoadUsers(dataFile string) (map[int64]User, error) {
	users := make(map[int64]User)

	data, err := os.ReadFile(dataFile)
	if err != nil {
		if os.IsNotExist(err) {
			// Файл не существует, возвращаем пустой словарь
			return users, nil
		}
		return nil, err
	}

	err = json.Unmarshal(data, &users)
	if err != nil {
		return nil, err
	}

	return users, nil
}

// KickChatMember исключает пользователя userID из чата chatID.
func KickChatMember(botToken string, chatID int64, userID int64) error {
	apiURL := "https://api.telegram.org/bot" + botToken + "/kickChatMember"

	data := url.Values{}
	data.Set("chat_id", strconv.FormatInt(chatID, 10))
	data.Set("user_id", strconv.FormatInt(userID, 10))

	resp, err := http.PostForm(apiURL, data)
	if err != nil {
		log.Print(err)
		return err
	}
	defer resp.Body.Close()

	_, err = io.ReadAll(resp.Body)
	if err != nil {
		log.Print(err)
		return err
	}

	return nil
}

// ParseUser парсит строку message и возвращает структуру User.
func ParseUser(message string) (User, error) {
	var user User
	tokens := strings.Split(message, " ")
	if len(tokens) != 3 {
		err := errors.New("неправильное количество аргументов")
		return user, err
	}
	birthdayText := tokens[2]
	birthdayText = strings.ReplaceAll(birthdayText, ".", "/")
	birthday, err := time.Parse("2/1/2006", birthdayText)
	if err != nil {
		return user, err
	}
	user.FirstName = tokens[0]
	user.LastName = tokens[1]
	user.Birthday = birthday
	return user, nil
}
